<?php

namespace App\Http\Controllers\Front;

use App\Interfaces\OrderService;
use App\Services\AlipayCustoms\AlipayCustom;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Services\Allinpay\Pay;
use App\Services\Allinpay\Responses\Pay as ResponsePay;
use App\Services\Allinpay\Utils\Form;
use App\Services\Wxpay\Models\UnifiedOrder;
use App\Exceptions\Front\WxpayException;
use App\Services\Wxpay\Models\OrderQuery;
use App\Services\Wxpay\Wxpay;
use App\Services\Wxpay\Sdk\Notify;
use App\Services\PingAnPay\PingAnPay;
use App\Services\PingAnPay\Reconciliation;
use App\Services\PingAnPay\Refund;
use App\Services\PingAnPay\RefundQuery;
use App\Services\PingAnPay\lib\pingan;
use App\Services\Wxpay\Models\Results;
use App\Models\Order;
use Auth,Log;
use Container;
use App\Interfaces\UserService;

class PayController extends Controller
{

    public function index($ids,Request $request,OrderService $orderService)
    {

        $idArr = explode(',',$ids);
        //过滤空值
        foreach( $idArr as $k=>$v){
            if( !$v )
                unset( $idArr[$k] );
        }
        $orders = [];

        foreach($idArr as $id){
            $theOrder= $orderService->getByOrderId($id);
            if ($theOrder->order_status==1){
                $orders[]=$theOrder;
            }

        }

        //
        if (isset($request->pay_test) && $request->pay_test=='open') {

            return view('front.pay.pay_test',compact(['orders','cancelTime']));
        }else{

            return view('front.pay.index',compact(['orders','cancelTime']));
        }

        // return view('front.pay.index',compact(['orders','cancelTime']));


    }

    public function success($order_id,OrderService $orderService){

        $order = $orderService->getByOrderId($order_id);



        return view('front.pay.success',compact(['order','order_id']));


    }


    public function fail($order_id,OrderService $orderService){

        $order = $orderService->getByOrderId($order_id);



        return view('front.pay.fail',compact(['order','order_id']));


    }


    public function request($order_id, $type, OrderService $orderService){

        $order = $orderService->getByOrderId($order_id);

        $subject = '';

        $goods_ids = '';

        foreach($order->orderGoods as $goods){

            $subject.='['.$goods->goods_name.']';

            $goods_ids .= '['.$goods->goods_id.']';
        }

       if ($order){

           switch($type){

               case 1:
                   //支付宝支付
                   return $this->aliPay($order->order_sn,$order->pay_price,$subject,$order->desc);
               break;

               case 2:
                   //通联支付
                   if($order->pay_status==0){

                       return $this->allinPay($order->order_sn, $order->pay_price, $order->create_time);
                   }//end if()
               break;

               case 3:
                   //微信支付
                   if($order->pay_status==0){

                       return $this->wxpay($order->order_sn, $order->pay_price, $subject, $goods_ids);
                   }//end if()
               break;

               case 4:
                   //平安银行支付
                   if($order->pay_status==0){

                       return $this->pingAnPay($order_id, $order->pay_price, $subject, $order->desc);
                   }//end if()
               break;
           }//end switch()


       }//end if()

    }

    //支付宝

    private function aliPay($order_sn,$pay_price,$subject,$description){

            // 创建支付单。
        $alipay = app('alipay.web');
        $alipay->setOutTradeNo($order_sn);
        $alipay->setTotalFee($pay_price);
        // $alipay->setSubject(substr($subject, 0, 32));
        $alipay->setSubject('subject');
        $alipay->setBody('');

        //$alipay->setQrPayMode('4'); //该设置为可选，添加该参数设置，支持二维码支付。

        //dd($alipay->getPayLink());
        // 跳转到支付页面。

        return redirect($alipay->getPayLink());

    }

    //支付宝同步跳转页面
    public function aliPayRedirectBack(Request $request,OrderService $orderService){


//        // 验证请求。
//        if (! app('alipay.web')->verify()) {
//            Log::notice('Alipay return query data verification fail.', [
//                'data' => $request->getQueryString()
//            ]);
//            return '失败';
//
//        }

        // 判断通知类型。
        switch ($request->get('trade_status')) {
            case 'TRADE_SUCCESS':
            case 'TRADE_FINISHED':

                $order_sn = $request->get('out_trade_no');


                $order_id = $orderService->orderPayBack(
                    $order_sn,
                    'alipay',
                    $request->get('trade_no'),
                    $request->get('notify_time'),
                    json_encode($request->all())
                    );

                if ($order_id){
                    return redirect('/pay/success/'.$order_id);
                }
                // TODO: 支付成功，取得订单号进行其它相关操作。
                Log::debug('Alipay notify get data verification success.', [
                    'out_trade_no' => $request->get('out_trade_no'),
                    'trade_no' => $request->get('trade_no')
                ]);
                break;
        }

        return '成功';
    }

    //支付宝服务回调
    public function aliPayServerBack(Request $request,OrderService $orderService){

        Log::debug('Alipay notify get data verification success.', [
            'out_trade_no' => $request->get('out_trade_no'),
            'trade_no' => $request->get('trade_no')
        ]);

        // 验证请求。
        if (! app('alipay.web')->verify()) {

            Log::notice('Alipay notify post data verification fail.', ['data' => $request->getContent()]);

            return 'fail';
        }

        // 判断通知类型。
        switch ($request->get('trade_status')) {
            case 'TRADE_SUCCESS':
            case 'TRADE_FINISHED':


            $pay_sn = $request->get('out_trade_no');


            $order_pay_id = $orderService->orderPayBack(
                $pay_sn,
                'alipay',
                $request->get('trade_no'),
                $request->get('notify_time'),
                json_encode($request->all())
            );

            if ($order_pay_id){
                return 'success';
            }

            Log::debug('Alipay notify get data verification success.', [
                'out_trade_no' => $request->get('out_trade_no'),
                'trade_no' => $request->get('trade_no')
            ]);

            break;
        }

        return 'success';
        return 'fail';

    }


    //阿里推关
    public function alipayPushCustom(AlipayCustom $alipayCustom){

        $alipayCustom->request();
    }


    public function allinPay($pay_sn, $pay_price, $create_time){

        $config = config('allinpay');
        $eorderinfo = config('eorderinfo');

        $ecCode = $eorderinfo['ecCode'];
        $ecName = $eorderinfo['ecName'];
        $customs_type = $eorderinfo['customs_type'];

        $allinPay = new  Pay($config['url'], $config['merchantId'], $config['key']);
        $allinPay->setUrl($config['pikUpUrl'] , $config['receiveUrl']);    //设置同步URL和异步URL(单选或多选)
        $allinPay->setLanguage();    //设置语言，默认为中文    可选项
        //$allinPay->parameter(date('Ymdhis'), 200)->request();
        $result = $allinPay->parameter($pay_sn, $pay_price, $payType = 0, $customs_type, $ecCode, $ecName);


        $title = '通联支付';
        $form = new Form($config['url'], $title, 'post');
        $form->setData($result['postData']);
        //$form->get();
        $form->submit();

    }//end func allinpay()


    //通联支付同步跳转页面
    public function allinPayRedirectBack(Request $request,OrderService $orderService){

        Log::debug('Allinpay return query data verification fail.', [
            'orderNo' => $request->get('orderNo'),
            'paymentOrderId' => $request->get('paymentOrderId')
        ]);

        $config = config('allinpay');

        $pay = new ResponsePay($config['key']);
        $result = $pay->chkVerify($_REQUEST);

        if($result){
            if($pay->errorMsg){
                echo $pay->errorMsg;
            }else{
                $pay_sn = $request->get('orderNo');

                $order_pay_id = $orderService->orderPayBack(
                    $pay_sn,
                    'allinpay',
                    $request->get('paymentOrderId'),
                    $request->get('payDatetime'),
                    json_encode($request->all())
                );
                return redirect('/pay/success/'.$order_pay_id);
            }
        }else{
            echo '不是通联数据，我们不鸟它!';
        }
        return 'success';
    }//end func


    //通联支付异步回调页面
    public function allinPayServiceBack(Request $request,OrderService $orderService){


        Log::debug('Allinpay notify post data verification fail.', [
            'orderNo' => $request->get('orderNo'),
            'paymentOrderId' => $request->get('paymentOrderId')
        ]);

        $config = config('allinpay');

        $pay = new ResponsePay($config['key']);
        $result = $pay->chkVerify($_REQUEST);

        if($result){
            if($pay->errorMsg){
                echo $pay->errorMsg;
            }else{
                $pay_sn = $request->get('orderNo');

                $order_pay_id = $orderService->orderPayBack(
                    $pay_sn,
                    'allinpay',
                    $request->get('paymentOrderId'),
                    $request->get('payDatetime'),
                    json_encode($request->all())
                );
                return 'success';
            }
        }else{
            echo '不是通联数据，我们不鸟它!';
        }
        return 'fail';

    }//end func


    /**
     * 生成微信支付二维码
     * @param  [type]       $order_id     [description]
     * @param  OrderService $orderService [description]
     * @return [type]                     [description]
     */
    public function wxpayScanUrl($order_id, OrderService $orderService){

        Log::info('微信支付生成二维码');

        $order = $orderService->getByOrderId($order_id);

        $subject = '';

        $goods_ids = '';

        foreach($order->orderGoods as $goods){

            $subject.='['.$goods->goods_name.']';

            $goods_ids .= '['.$goods->goods_id.']';
        }

        $result = $this->wxpay($order->order_sn, $order->pay_price, $subject, $goods_ids);


        if (isset($result['code_url'])) {

            // $code_url = 'weixin://wxpay/bizpayurl?pr=R5zsq92';

            $code_url = $result['code_url'];

            $qr_code_url = $this->QRcode($code_url, $order->order_sn);

            $return['data'] = $qr_code_url;

            // echo '<img src="'.$qr_code_url.'" /><hr/>';
        }else{

            $return['status'] = 0;

            if (isset($result['return_code'])) {

                switch ($result['return_code']) {

                    case 'SUCCESS':

                        if (isset($result['result_code']) && $result['result_code'] == 'FAIL') {

                            $return['message'] = $result['err_code_des'];
                        }

                        break;

                    case 'FAIL':

                        $return['message'] = $result['return_msg'];

                        break;
                }
            }
        }

        return $return;
    }


    /**
     * [微信支付]
     * @param  [type] $order_sn    [description]
     * @param  [type] $pay_price   [description]
     * @param  [type] $create_time [description]
     * @return [type]              [description]
     */
    public function wxpay($order_sn, $pay_price, $subject, $goods_ids)
    {
        $return = ['status'=>1, 'message'=>'', 'data'=>''];

        // $wxpay = app('wxpay');

        $wxpay = new Wxpay(config('latrell-wxpay'));

        $native = $wxpay->native();

        $input = new UnifiedOrder();

        $trade_type = 'NATIVE';

        $input->setOutTradeNo($order_sn);
        // $input->setBody(substr($subject, 0, 127));
        $input->setBody('subject');
        $input->setTotalFee(intval(strval($pay_price*10*10)));
        // $input->setTotalFee(1);
        $input->SetTrade_type($trade_type);
        $input->setProductId($goods_ids);
        $input->SetNotify_url(config('latrell-wxpay.notify_url'));
        // $input->SetNotify_url('http://117.158.194.99:8080/wxnotify.php');

        $result = $native->GetPayUrl($input);

        return $result;
    }

    /**
     * [微信支付异步回调]
     * @param  string $order_id [订单id]
     * @return [type]        [description]
     */
    public function wxPayServerBack(Request $request, OrderService $orderService)
    {
        $return = ['status'=>1, 'message'=>'', 'data'=>''];

        Log::info('微信支付异步回调页面');

        $xml = file_get_contents('php://input');

        Log::info('回调结果参数 xml:'.$xml);

        $wxpay = new Wxpay(config('latrell-wxpay'));

        $notify = $wxpay->notify();

        $result = $notify->Handle();

        if ($result && $result['return_code']=='SUCCESS') {

            // $xml = file_get_contents('php://input');

            //如果返回成功则验证签名
            try {

                $resultParam = Results::Init($xml);

                // Log::info('回调结果参数 result：'.json_encode($resultParam));

            } catch (WxpayException $e) {

                $return['status'] = 0;

                $return['message'] = '微信异步回调信息有误';

                return json_encode($return);
            }

            if ($resultParam['out_trade_no']) {

                $orders = Order::where('order_sn', $resultParam['out_trade_no'])->first();

                if ($orders && $orders->order_status==1) {

                    //修改订单状态

                    $order_pay_id = $orderService->orderPayBack(
                        $resultParam['out_trade_no'],
                        'wxpay',
                        $resultParam['transaction_id'],
                        $resultParam['time_end'],
                        json_encode($resultParam)
                    );

                    if ($order_pay_id){

                        return json_encode($return);
                        // return 'success';
                    }

                    Log::debug('Alipay notify get data verification success.', [
                        'out_trade_no' => $resultParam['out_trade_no'],
                        'transaction_id' => $resultParam['transaction_id']
                    ]);
                }
            }
        }else{

            $return['status'] = 0;

            $return['message'] = '微信异步回调信息验证有误';
        }

        return json_encode($return);

    }


    /**
     * [生成二维码]
     * @param string $value [description]
     */
    public function QRcode($code_url, $scan_name = 'wxpay')
    {

        //set it to writable location, a place for temp generated PNG files
        // $PNG_TEMP_DIR = dirname(__FILE__).DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR;
        // $PNG_TEMP_DIR = public_path().DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR;
        /*$PNG_TEMP_DIR = DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR;

        //html PNG location prefix
        $PNG_WEB_DIR = DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR.$scan_name.'.png';

        //ofcourse we need rights to create temp dir
        if (!file_exists($PNG_TEMP_DIR))
            mkdir($PNG_TEMP_DIR);

        $filename = $PNG_TEMP_DIR.$scan_name.'.png';*/

        //processing form input
        //remember to sanitize user input in real-life solution !!!
        $errorCorrectionLevel = 'L';
        if (isset($_REQUEST['level']) && in_array($_REQUEST['level'], array('L','M','Q','H')))
            $errorCorrectionLevel = $_REQUEST['level'];

        $matrixPointSize = 4;
        if (isset($_REQUEST['size']))
            $matrixPointSize = min(max((int)$_REQUEST['size'], 1), 10);

        if (isset($_REQUEST['data'])) {

            if (trim($_REQUEST['data']) == '')
                die('data cannot be empty! <a href="?">back</a>');

            // user data
            $filename = $PNG_TEMP_DIR.'test'.md5($_REQUEST['data'].'|'.$errorCorrectionLevel.'|'.$matrixPointSize).'.png';

            \PHPQRCode\QRcode::png($_REQUEST['data'], $filename, $errorCorrectionLevel, $matrixPointSize, 2);
        } else {

            //default data
            // echo 'You can provide data in GET parameter: <a href="?data=like_that">like that</a><hr/>';

            // \PHPQRCode\QRcode::png($code_url, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
            \PHPQRCode\QRcode::png($code_url, false, $errorCorrectionLevel, $matrixPointSize, 2);
            $xmlstr =  @$GLOBALS[HTTP_RAW_POST_DATA];
            // if(empty($xmlstr)) $xmlstr = file_get_contents('php://input');
        }

        // return $PNG_WEB_DIR;
    }


    /**
     * 微信订单查询
     * @param  string $value [description]
     * @return [type]        [description]
     */
    public function wxpayOrderQuery($order_sn, $return_type='array')
    {
        $return = ['status'=>1, 'message'=>'', 'data'=>'', 'xml'=>''];
        Log::info('根据订单号['.$order_sn.']查询在微信的支付结果');

        $user=Auth::user();

        if (empty($user->id)) {

            $return['status'] = 0;

            $return['message'] = '用户id获取失败';

            return $return;
        }

        $order_sn = Order::where('user_id', $user->id)->where('order_sn', $order_sn)->pluck('order_sn');
        // $order_sn = Order::where('user_id', 59)->where('order_sn', $order_sn)->pluck('order_sn');


        if (empty($order_sn)) {

            $return['status'] = 0;

            $return['message'] = '订单id和用户不符';

            return $return;
        }

        $wxpay = new Wxpay(config('latrell-wxpay'));

        $orderQuery = $wxpay->OrderQuery();

        $input = new OrderQuery();

        $input->setOutTradeNo($order_sn);

        $result = $orderQuery->queryOrder($input);

        switch ($result['return_code']) {

            case 'SUCCESS':

                switch ($result['result_code']) {

                    case 'SUCCESS':

                        $return['data'] = $result;

                        //将数组转换为xml格式
                        $xml = simplexml_load_string('<request />');

                        $this->arrayToXmlLeen($return['data'], $xml);

                        $return['xml'] = $xml->saveXML();


                        if ($result['trade_state']!=='SUCCESS') {

                            $return['status'] = 0;

                            switch ($result['trade_state']) {
                                case 'SUCCESS':
                                    $return['status'] = 1;

                                    // $return['message'] = '支付成功';
                                    $return['msg'] = '支付成功';

                                    break;

                                case 'REFUND':

                                    // $return['message'] = '转入退款';
                                    $return['msg'] = '转入退款';

                                    break;


                                case 'NOTPAY':
                                    // $return['status'] = 1;

                                    // $return['message'] = '未支付';
                                    $return['msg'] = '未支付';

                                    break;


                                case 'CLOSED':

                                    // $return['message'] = '已关闭';
                                    $return['msg'] = '已关闭';

                                    break;


                                case 'REVOKED':

                                    // $return['message'] = '已撤销（刷卡支付）';
                                    $return['msg'] = '已撤销（刷卡支付）';

                                    break;


                                case 'USERPAYING':

                                    // $return['message'] = '用户支付中';
                                    $return['msg'] = '用户支付中';

                                    break;


                                case 'PAYERROR':

                                    // $return['message'] = '支付失败(其他原因，如银行返回失败)';
                                    $return['msg'] = '支付失败(其他原因，如银行返回失败)';

                                    break;
                            }

                            return $return;
                        }

                        break;

                    case 'FAIL':

                        $return['status'] = 0;

                        // $return['message'] = '错误码：'.$result['err_code'].'||错误描述：'.$result['err_code_des'];
                        $return['msg'] = '错误码：'.$result['err_code'].'||错误描述：'.$result['err_code_des'];

                        return $return;

                        // return false;

                        break;
                }

                break;

            case 'FAIL':

                $return['status'] = 0;

                // $return['message'] = $result['return_msg'];
                $return['msg'] = $result['return_msg'];

                return $return;


                // return false;

                break;
        }

        if ($return_type=='array') {

            return $return;
        }else{

            return json_encode($return);
        }
    }

    /**
     * [将数组转换为xml格式]
     * @param  [type] $ar  [description]
     * @param  [type] $xml [description]
     * @return [type]      [description]
     */
    public function arrayToXmlLeen($ar, $xml)
    {
        foreach($ar as $k=>$v) {
            if(is_array($v)) {
                $x = $xml->addChild($k);
                $this->arrayToXmlLeen($v, $x);
            }else $xml->addChild($k, $v);
        }
    }


    /**
     * 平安银行支付
     */
    public function pingAnPay($order_id, $pay_price, $subject, $desc='')
    {


        // $pingAnPay = new PingAnPay();

        $payClass = new PingAnPay();

        $subject = iconv('utf-8', 'gbk', $subject);
        Log::info('平安银行支付 order_id:'.$order_id);

        $payClass->run($order_id, $pay_price, $subject, $desc);


        // dd('平安银行支付');

    }

    /**
     * 平安银行支付异步回调
     */
    public function pingAnServerBack($order_id, Request $request, OrderService $orderService)
    {

        Log::info('平安银行支付异步回调 order_id:'.$order_id);

        header("Content-Type: text/html;charset=utf-8");

        $orig = $_POST['orig'];
        $sign = $_POST['sign'];


        // $tTrustPayCertFile = 'merchant/paygate.cer';
        $tTrustPayCertFile = config('pinganpay.t_trust_pay_cert_file');

        // require_once 'lib/pingan.php';
        $pingan = new pingan();

        //1、进行数据转码
        $orig = base64_decode($orig);
        $sign = base64_decode($sign);

        //2、验证签名是否正确
        $result = $pingan->validate($orig, $sign, $tTrustPayCertFile);
        if ($result) {
            echo 'success';
        } else {
            exit('error');
        }

        Log::info('原始数据：'.$orig);
        Log::info('签名：'.$sign);
        Log::info('校验结果：'.$result);

        // $orig = mb_convert_encoding($orig, 'gbk', 'utf-8');
        $orig = mb_convert_encoding($orig, 'utf-8', 'gbk');

        //3、将xml数据转换成array
        $orig_data = $pingan->xml_to_array($orig);
        // print_r($orig_data);

        Log::info('支付结果：'.$orig_data['status']);

        Log::info(json_encode($orig_data));

        if ($orig_data['status'] == '01') {

            $orders = Order::find($order_id);

            // Log::info(Response()->Json($orders->toArray()));

            if ($orders && $orders->order_status==1) {

                //修改订单状态

                $order_pay_id = $orderService->orderPayBack(
                    $orders->order_sn,
                    'pinganpay',
                    $orig_data['orderId'],
                    $orig_data['date'],
                    json_encode($orig_data)
                );

                if ($order_pay_id){

                    // return json_encode($orig_data);
                    return 'success';
                }
                Log::debug('Alipay notify get data verification success.', [
                    'order_sn' => $orders->order_sn,
                    'orderId' => $orig_data['orderId']
                ]);

                //break;
            }
        }
    }


    //平安银行同步跳转页面
    public function pingAnPayRedirectBack($order_id, Request $request,OrderService $orderService){

        Log::info('平安银行支付同步回调 order_id:'.$order_id);

        header("Content-Type: text/html;charset=utf-8");

        $orig = $_POST['orig'];
        $sign = $_POST['sign'];

        // $tTrustPayCertFile = 'merchant/paygate.cer';
        $tTrustPayCertFile = config('pinganpay.t_trust_pay_cert_file');

        // require_once 'lib/pingan.php';
        $pingan = new pingan();

        //1、进行数据转码
        $orig = $pingan->_base64_url_decode($orig);
        $sign = $pingan->_base64_url_decode($sign);

        //2、验证签名是否正确
        $result = $pingan->validate($orig, $sign, $tTrustPayCertFile);
        if ($result) {
            // echo 'success';
        } else {
            return redirect('/pay/fail/'.$order_id);
            exit('error');
        }

        // $orig = mb_convert_encoding($orig, 'gbk', 'utf-8');
        $orig = mb_convert_encoding($orig, 'utf-8', 'gbk');

        //3、将xml数据转换成array
        $orig_data = $pingan->xml_to_array($orig);
        // print_r($orig_data);


        Log::info('支付结果：'.$orig_data['status']);

        Log::info(json_encode($orig_data));

        if ($orig_data['status'] == '01') {

            return redirect('/pay/success/'.$order_id);
        }
        // return '成功';
    }


    /**
     * 平安支付单笔订单状态查询接口
     * @param  [type] $pay_num [支付单号]
     * @return [type]          [description]
     */
    public function pingAnSingleOrderQuery($pay_num)
    {

        $reconciliation = new Reconciliation();

        $result = $reconciliation->singleOrderQuery($pay_num);

        if ($result['status']=='01') {

            echo '<BR>查询成功';
            dd($result);
        }else{

            echo '<BR>错误码:'.$result['errorCode'];
            echo '<BR>错误说明:'.$result['errorMsg'];
        }
    }


    /**
     * 平安支付单笔订单退款接口
     * @param  [type] $order_id [订单id]
     * @param  string $reason   [退款原因]
     * @param  string $remark   [备注信息]
     * @return [type]           [description]
     */
    public function pingAnSingleOrderRefund($order_id, $reason = '', $remark = '')
    {


        $order = Order::find($order_id);

        if ($order) {

            $refund_amt = $order->pay_price;

            $pay_num = $order->pay_num;

            $refund = new Refund();

            $result = $refund->singleOrderRefund($order_id, $pay_num, $refund_amt, $reason, $remark);

            if ($result['status']=='01') {

                echo '<BR>退款申请成功';
                echo '<BR>支付单号：'.$result['orderId'];
                echo '<BR>退款单号：'.$result['refundNo'];
            }else{

                echo '<BR>错误码:'.$result['errorCode'];
                echo '<BR>错误说明:'.$result['errorMsg'];
            }

            dd($result);
        }
    }


    /**
     * 平安支付退款申请异步通知接收处理
     * @param string $value [description]
     */
    public function pingAnRefundServer($order_id)
    {

        Log::info('订单id为['.$order_id.']的订单退款完成');

    }


    /**
     * 订单退款查询
     * @param  [type] $refund_no [退款单号]
     * @return [type]            [description]
     */
    public function pingAnRefundQuery($start_time='', $end_time='')
    {

        $curent_time = date('YmdHis');

        if (empty($start_time)) {

            $start_time = $curent_time;
        }

        if (empty($end_time)) {

            $end_time = $curent_time;
        }

        $refundQuery = new RefundQuery();

        $result = $refundQuery->singleOrderRefundQuery($start_time, $end_time);

        if ($result['sumCount'] && $result['sumCount']>0) {

            echo '<BR>交易总笔数：'.$result['sumCount'];
            echo '<BR>支付总金额：'.$result['sumAmount'];

        }else{

            echo '<BR>错误码:'.$result['errorCode'];
            echo '<BR>错误说明:'.$result['errorMsg'];
        }

        dd($result);

    }



    /**
     * 调用平安接口发送验证码给用户
     * @param  [type] $telphone [用户手机号码]
     * @return [type]           [description]
     */
    public function pingAnSendMsg($telphone)
    {

        // $url = 'http://127.0.0.1:7072/';
        $url = config('pinganpay.B2BiC_URL');

        $post_data = [];

        $post_data['partner'] = config('pinganpay.partner');
        // $post_data['partner'] = '10009';        //合作方身份ID,合作方ID，由银行分配为每个合作方分配唯一用户号。平安技术给的：10021，实际测试使用：10009
        $post_data['mobile'] = $telphone;
        $post_data['optype'] = '01';            //固定值01

        $params_json = json_encode($post_data);

        $params_length = strlen($params_json);


        $version = 'A001';

        $encode = 'GBK';

        $protocol = 'http';

        // $customer_code = '00102079900001231000';             //外联客户代码，测试使用：00102079900001231000，实际测试使用：H009（企业上线的时候由银行分配）
        // $customer_code = 'H009';
        $customer_code = config('pinganpay.customer_code');

        $transaction_code = 'SCFP01';

        $ymd = date('Ymd');

        $his = date('His');

        // $trand_no = $ymd.$his;
        $trand_no = time().rand(1000,9999);

        $operator = '';

        $service_type = '01';

        $attachments_num = 0;

        $message_header = $this->messageHeader($version, $encode, $protocol, $customer_code, $params_length, $transaction_code, $ymd, $his, $trand_no, $attachments_num);

        $message_params = $message_header.$params_json;


        Log::info('请求平安短信码接口报文:'.$message_params);

        $result = $this->curl($url, $message_params);

        $result = mb_convert_encoding($result, 'utf-8', 'gbk');

        Log::info('请求平安短信码接口结果:'.$result);

        $return = ['status'=>'1', 'message'=>'短信发送成功!', 'errorcode'=>'000000', 'remainTime'=>'0'];

        //成功：{"errorcode":"000000","errormsg":"短信发送成功!","status":"success"}
        //已注册过：{"errorcode":"100002","errormsg":"短信验证码发送失败，请重新发送!","status":"fail"}
        //失败：{"errorcode":"100003","errormsg":"请勿频繁发送短信验证码!","remainTime":"94","status":"fail"}
        $result = json_decode(substr($result, 222));

        if ($result->status == 'fail') {

            $return['status'] = 0;

            $return['message'] = $result->errormsg;

            $return['errorcode'] = $result->errorcode;

            if ($result->errorcode == '100003') {

                $return['remainTime'] = $result->remainTime;
            }

        }

        // return $result;
        return json_encode($return);
    }


    /**
     * 用户实名认证
     * @param  [type] $identity          [身份证号]
     * @param  [type] $verification_code [验证码]
     * @return [type]                    [description]
     */
    public function identityVerification(Request $request, UserService $userService)
    {

        $return = ['status'=>'1', 'message'=>'短信发送成功!', 'errorcode'=>'000000', 'remainTime'=>'0'];

        // $url = 'http://127.0.0.1:7072/';
        $url = config('pinganpay.B2BiC_URL');

        $post_data = [];

        //合作方身份ID，平安技术给的:10021，实际测试使用:10009
        $post_data['partner'] = config('pinganpay.partner');
        // $post_data['partner'] = '10009';

        //短信验证码
        if (isset($request->verification_code) && !empty($request->verification_code)) {

            $post_data['otpcode'] = $request->verification_code;
        }else{

            $return['status'] = 0;

            $return['message'] = '短信码不能为空';

            return $return;
        }

        //客户ID，客户在合作方系统的唯一标识，当调用方上送该值时，橙e会校验该值的唯一性
        if (isset($request->identity) && !empty($request->identity)) {

            $post_data['cstid'] = $request->identity;
        }else{

            $return['status'] = 0;

            $return['message'] = '客户ID不能为空';

            return $return;
        }

        //登录用户名,橙e的登录用户名，当调用方上送该值时，橙e会校验登录名的唯一性,可空
        $post_data['loginname'] = '';

        //登录密码,橙e的登录密码，橙e会为注册用户设置一个默认密码,可空
        $post_data['loginpwd'] = '';

        //证件类型，固定填：1 (身份证)
        $post_data['certtype'] = 1;

        //证件号码
        if (isset($request->identity) && !empty($request->identity)) {

            $post_data['certno'] = $request->identity;
        }else{

            $return['status'] = 0;

            $return['message'] = '证件号码不能为空';

            return $return;
        }

        //用户姓名
        if (isset($request->name) && !empty($request->name)) {

            $post_data['name'] = $request->name;
        }else{

            $return['status'] = 0;

            $return['message'] = '用户姓名不能为空';

            return $return;
        }

        //用户手机号
        if (isset($request->mobile) && !empty($request->mobile)) {

            $post_data['mobile'] = $request->mobile;
        }else{

            $return['status'] = 0;

            $return['message'] = '用户手机号不能为空';

            return $return;
        }

        //用户邮箱,可空
        if (isset($request->email) && !empty($request->email)) {

            $post_data['email'] = $request->email;
        }else{

            $post_data['email'] = '';
        }

        //邀请码,固定填:afuyig,可空
        if (isset($request->invitecode) && !empty($request->invitecode)) {

            $post_data['invitecode'] = $request->invitecode;
        }else{

            $post_data['invitecode'] = 'afuyig';
        }



        $params_json = json_encode($post_data);

        $params_length = strlen($params_json);


        $version = 'A001';

        $encode = 'GBK';

        $protocol = 'http';

        // $customer_code = '00102079900001231000';             //外联客户代码，测试使用：00102079900001231000，实际测试使用：H009（企业上线的时候由银行分配）
        // $customer_code = 'H009';
        $customer_code = config('pinganpay.customer_code');

        $transaction_code = 'SCFP03';

        $ymd = date('Ymd');

        $his = date('His');

        // $trand_no = $ymd.$his;
        $trand_no = time().rand(1000,9999);

        $operator = '';

        $service_type = '01';

        $attachments_num = 0;

        $message_header = $this->messageHeader($version, $encode, $protocol, $customer_code, $params_length, $transaction_code, $ymd, $his, $trand_no, $attachments_num);

        $message_params = $message_header.$params_json;

        // $message_params = mb_convert_encoding($message_params, 'utf-8', 'gbk');

        Log::info('请求橙e网注册接口报文:'.$message_params);

        $result = $this->curl($url, $message_params);

        $result = mb_convert_encoding($result, 'utf-8', 'gbk');

        Log::info('请求橙e网注册接口结果:'.$result);
        $return = ['status'=>'1', 'message'=>'短信发送成功!', 'errorcode'=>'000000', 'remainTime'=>'0'];

        //成功：{"cstid ":"411024198903067770","errorcode":"000000","errormsg":"注册橙e网用户成功","partner ":"10009","scfpid":"OBPU0020160812003689","status":"success"}
        //失败：{"cstid ":"411024198903067770","errorcode":"100004","errormsg":"短信验证码校验失败!","partner ":"10009","status":"fail"}
        //失败：{"cstid ":"411024198903067777","errorcode":"100005","errormsg":"证件号码非法!","partner ":"10009","status":"fail"}
        // $result = substr($result, 222);
        $result = json_decode(substr($result, 222));

        /*$result = json_decode($result);

        if ($result->status == 'success') {

        }*/

        if ($result->status == 'fail') {

            $return['status'] = 0;

            $return['message'] = $result->errormsg;

            $return['errorcode'] = $result->errorcode;

            if ($result->errorcode == '100003') {

                $return['remainTime'] = $result->remainTime;
            }

        }elseif ($result->status == 'success') {

            //增加用户注册信息
            $userService->addIdVerity(Auth::user()->id, $request->name, 1, $request->identity);

        }
        return $return;
    }

    /**
     * 报文头
     * @param string $value [description]
     */
    public function messageHeader($version, $encode, $protocol, $customer_code, $params_length, $transaction_code, $ymd, $his, $trand_no, $attachments_num)
    {

        $type_string = 'string';

        $type_number = 'number';

        ########## 必填项 ##########

        //报文版本：A001定长222报文头+报文体，客户端需要按此报文头上送。A002 无报文头，客户端不上送以A001开头的报文，由B2BiC客户端增加A002开头的222位报文头
        $message_version = $version;

        $message_version = $this->completion($message_version, 4, $type_string);


        //目标系统：18:橙e网门户
        $message_target = '18';

        $message_target = $this->completion($message_target, 2, $type_string);


        //报文编码：01：GBK缺省; 02：UTF8; 03：unicode; 04：iso-8859-1; 建议使用GBK编码
        switch ($encode) {

            case 'GBK':
                $message_encode = '01';
                break;

            case 'UTF-8':
                $message_encode = '02';
                break;

            case 'unicode':
                $message_encode = '03';
                break;

            case 'iso-8859-1':
                $message_encode = '04';
                break;

            default:
                $message_encode = '01';
                break;
        }

        $message_encode = $this->completion($message_encode, 2, $type_string);


        //通讯协议：01:tcpip 缺省; 02：http; 03：webservice
        switch ($protocol) {

            case 'tcpip':
                $message_protocol = '01';
                break;

            case 'http':
                $message_protocol = '02';
                break;

            case 'webservice':
                $message_protocol = '03';
                break;

            default:
                $message_protocol = '01';
                break;
        }

        $message_protocol = $this->completion($message_protocol, 2, $type_string);


        //外联客户代码：测试使用(00102079900001231000).（企业上线的时候由银行分配）
        $message_customer_code = $customer_code;

        $message_customer_code = $this->completion($message_customer_code, 20, $type_string);


        //接收报文长度：XML报文体数据的字节长度；不包括附件内容、签名内容的长度（XML长度）。注：应该是json格式的长度
        $message_receive_lenght = $params_length;

        $message_receive_lenght = $this->completion($message_receive_lenght, 10, $type_number);


        //交易码：供应链报文统一交易码SC00,默认填写000000，实际测试发送验证码使用:scfp01，注册使用:SCFP03
        $message_transaction_code = $transaction_code;
        // $message_transaction_code = 'scfp01';

        $message_transaction_code = $this->completion($message_transaction_code, 6, $type_string);


        ########## 选填项 #########

        //操作员代码
        // $message_operator = '00000';
        $message_operator = '';

        $message_operator = $this->completion($message_operator, 5, $type_string);


        //服务类型： 01:请求; 02:应答;
        $message_service_type = 01;

        $message_service_type = $this->completion($message_service_type, 2, $type_string);


        ########## 必填项 ##########

        //交易日期：yyyymmdd
        $message_transaction_date = $ymd;

        //交易时间：hhmmss
        $message_transaction_time = $his;

        //请求方系统流水号：唯一标识一笔交易（企业随机生成唯一流水号）。备注：（如果某种交易要有多次请求的才能完成的，多个交易请求包流水号要保持一致）
        $message_trand_no = $trand_no;

        $message_trand_no = $this->completion($message_trand_no, 20, $type_string);


        ########## 选填项 #########

        //返回码：请求非必输，请求时填写000000
        $message_return_code = '000000';

        $message_trand_no = $this->completion($message_trand_no, 6, $type_string);


        //返回描述：格式为 “:交易成功”；其中冒号为英文格式半角。
        // $message_return_desc = ':交易成功';
        $message_return_desc = '';

        $message_return_desc = $this->completion($message_return_desc, 100, $type_string);


        //后续包标志：0-结束包，1-还有后续包,同请求方流水号一起运作,请求方系统流水号要和第一次保持一致
        $message_follow_up_sign = '0';

        $message_follow_up_sign = $this->completion($message_follow_up_sign, 1, $type_string);


        //请求次数：如果有后续包请求, 第一次 000, 第二次 001, 第三次 002依此增加, 请求方系统流水号要和第一次保持一致。
        $message_request_num = '000';

        $message_request_num = $this->completion($message_request_num, 3, $type_string);


        //签名标识：0:不签名; 1:签名 （填0，企业不管，由银行客户端完成）
        $message_signature_logo = '0';

        //签名数据包格式：0:裸签（填1，企业不管，由银行客户端完成）; 1:PKCS7
        // $message_signature_digital_formate = '1';
        $message_signature_digital_formate = '0';

        //签名算法：RSA-SHA1
        // $message_signature_algorithm = 'RSA-SHA1';
        $message_signature_algorithm = '0';

        $message_signature_algorithm = $this->completion($message_signature_algorithm, 12, $type_string);


        ########## 必填项 ##########

        //签名数据长度：签名报文数据长度,填写0
        $message_signature_digital_lenth = 0;

        $message_signature_digital_lenth = $this->completion($message_signature_digital_lenth, 10, $type_string);


        //附件数目：0:没有,默认为 0; 有的话填具体个数，最多9个，目前只支持1
        // $message_attachments_num = $attachments_num;
        $message_attachments_num = 0;

        $message_attachments_num = $this->completion($message_attachments_num, 1, $type_string);


        //报文头
        $message_header = $message_version.$message_target.$message_encode.$message_protocol.$message_customer_code.$message_receive_lenght.$message_transaction_code;

        $message_header .= $message_operator.$message_service_type;

        $message_header .= $message_transaction_date.$message_transaction_time.$message_trand_no;

        $message_header .= $message_return_code.$message_return_desc.$message_follow_up_sign.$message_request_num.$message_signature_logo.$message_signature_digital_formate.$message_signature_algorithm;

        $message_header .= $message_signature_digital_lenth.$message_attachments_num;

        // $message_header = $this->completion($message_header, 222, 'string');

        return $message_header;
    }

    /**
     * 补全至指定长度
     * @param  [type] $str    [要补全的变量]
     * @param  [type] $length [要补全到的长度]
     * @param  [type] $type   [变量类型，字符串：在后面用空格补全，数字：在前面用0补全]
     * @return [type]         [description]
     */
    public function completion($str, $length, $type)
    {

        $str_length = strlen($str);

        if ($str_length < $length) {

            for ($i=$str_length; $i < $length; $i++) {

                switch ($type) {

                    case 'string':
                        $str .= ' ';
                        break;

                    case 'number':
                        $str = '0'.$str;
                        break;

                    default:
                        return $str;
                        break;
                }
            }
        }

        return $str;
    }


    //转码为gbk
    public function transcodingToGBK($string='')
    {

        $encode = mb_detect_encoding($string, array('ASCII','UTF-8','GB2312','GBK','BIG5'));

        switch ($encode) {
            case 'ASCII':

                $string = mb_convert_encoding($string, 'gbk', 'ASCII');
                break;
            case 'UTF-8':

                $string = mb_convert_encoding($string, 'gbk', 'utf-8');
                break;
            case 'GB2312':

                $string = mb_convert_encoding($string, 'gbk', 'GB2312');
                break;
            case 'BIG5':

                $string = mb_convert_encoding($string, 'gbk', 'BIG5');
                break;
        }
        return $string;
    }




    /**
     * PHP模拟POST的HTTPS的请求
     * @param string $url
     * @param array  $params
     * @return string
     */
    public function curl($url, $params) {

        $ch = curl_init();

        // $header[] = "Content-type: application/json; charset=GBK";//定义content-type为json

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_POST, true);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //HTTPS����

        // curl_setopt($ch, CURLOPT_HTTPHEADER, $header);//定义请求类型

        $result = curl_exec($ch);

        curl_close($ch);

        return $result;
    }
}
